var reminderFox_download_headless;
var reminderFox_remoteTimeStamp;
var  reminderFox_editWindowCallback;
var reminderFox_subscriptionCallback;
var reminderFox_subscriptionReminders;

function reminderFox_download_statustxt(aStatus, aError){
	if (reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI) {
		document.getElementById("status").value = (aError) ? reminderFox_download_getErrorMsg(aError) : aStatus;
	}
	else {
		var value = null;
		if (aError == -1) {
			value = aStatus;
		}
		else {
			value = (aError) ? reminderFox_download_getErrorMsg(aError) : aStatus;
		}
		reminderFox_logMessageLevel("Download (headless): " + new Date() + " " + value, REMINDER_FOX_LOG_LEVEL_FINE);
	}
}

function reminderFox_download_Startup()
{
  reminderFox_download_headless = REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI;
  reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.ready.label"),0);
  reminderFox_editWindowCallback = null;
  setTimeout(reminderFox_downloadDelayedStartup, 0);

}

function reminderFox_download_Startup_headless(headlessLevel, callback)
{
  reminderFox_download_headless = headlessLevel; 
  reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.ready.label"),0);
  reminderFox_editWindowCallback = callback;
  reminderFox_downloadDelayedStartup();
}

function reminderFox_download_Startup_headless_URL(headlessLevel, callback, url, downloadedReminders, downloadedTodos)
{
  reminderFox_download_headless = headlessLevel; 
  reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.ready.label"),0);
  reminderFox_subscriptionCallback = callback;
 reminderFox_subscriptionReminders = downloadedReminders;
 
   var _ioService = Components.classes["@mozilla.org/network/io-service;1"]
               	   .getService(Components.interfaces.nsIIOService);

  var downloadURI = _ioService.newURI(url,null,null);
  if(gDownloadService.start(downloadURI,reminderFox_downloadCallbackURL))
    reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.request.label"),0);
  else {
    //statustxt(reminderFox_getBundle().getString("rf.net.done"),0);
    reminderFox_downloadCallbackURL(reminderFox_getBundle().getString("rf.net.done"),-1);
  }
}


function reminderFox_downloadCallbackURL(aStatus,aError)
{
  if(aStatus != reminderFox_getBundle().getString("rf.net.done") && aError==0) {
    reminderFox_download_statustxt(aStatus,aError);
    return;
}

 switch(aError){
 
  case -2:
    reminderFox_download_statutxt(aStatus,aError);
	if (reminderFox_subscriptionCallback != null ) {
		var statustxt = (aError)?	reminderFox_download_getErrorMsg(aError):aStatus;
 		reminderFox_subscriptionCallback (statustxt, 0  );
	}    
    return;
    break;
  case 0:
  
  	 	reminderFox_logMessageLevel( "Downloading subscribed reminders...", REMINDER_FOX_LOG_LEVEL_FINE ); 
  	 	
		if (reminderFox_subscriptionCallback != null ) {
  	 		reminderFox_subscriptionCallback ( reminderFox_getBundle().getString("rf.add.network.status.download.label"), 0  );
		}
		  var processtime = 0;
		     if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI) {
		    		processtime = document.getElementById("processtime");
		    	}
		    var time=gDownloadService.time;
		    processtime.value=gDownloadService.length.toString()
		                      +" bytes  "+(time/1000).toString() + " sec  ";
		    var start=new Date();

		    reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.process.label"),0);
		    try{
		    	reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.download.importing.label"),0);
			
				var is = Components.classes["@mozilla.org/io/string-input-stream;1"]
					.createInstance( Components.interfaces.nsIStringInputStream );
				is.setData(gDownloadService.data,-1); // -1 ... length should be computed
				
			
				var downloadedTodos = new Array();
				reminderFox_readInRemindersAndTodosICSFromStream(reminderFox_subscriptionReminders, downloadedTodos, is, true);
						    
			    // if successful, close immediately
			 	if ( window.arguments != null && window.arguments[0] != null && window.arguments[0].closeOnNoErrors == 1) {
			  		close();
			  		return;
			  	}
	
		        var end=new Date();
		        processtime.value += ((end.getTime() - start.getTime())/1000).toString()+" sec";
		        reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.net.done"),0);
				
				if (reminderFox_subscriptionCallback != null ) {
		  	 		reminderFox_subscriptionCallback (null, 2, reminderFox_subscriptionReminders   );
				}		        
		        
		    }catch(e){
		      reminderFox_download_statustxt(e.toString(),0);
		      if(e && e.toString().match(/^rem\:(.+)$/))
		        reminderFox_download_statustxt(RegExp.$1,0);
		      return;
		    }	
  	
  
    break;
  default:
    var status=aError % 0x804b0000;  
   
  	  reminderFox_download_statustxt(aStatus,aError);

		if (reminderFox_subscriptionCallback != null ) {
			var statustxt = (aError)?	reminderFox_download_getErrorMsg(aError):aStatus;
	 		reminderFox_subscriptionCallback (statustxt, 0  );
		}      	  
    break;
   }
  
  if ( aError == 0 ) { 
      if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI) {
		reminderFox_closeWindow();
  	  }
  }
}



function reminderFox_downloadDelayedStartup()
{
  var _downloadURL = "";
  var _ioService = Components.classes["@mozilla.org/network/io-service;1"]
               	   .getService(Components.interfaces.nsIIOService);

  var proto = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_PROTO);
  var address = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_ADDRESS);
  var _username = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_USERNAME);
  
  if ( address == null || address.length == 0 ) {
  	  reminderFox_downloadCallback(reminderFox_getBundle().getString("rf.net.done"),-1);
  	  return;
  }
  
  var loginData = {
    ljURL : proto + "://" + address,
    username : _username,
    password : ''
  };

  loginData = reminderFox_getPassword(loginData);
  

  // if no username is specified, allow to pass through
  if ((_username != null && _username != "" ) && (loginData == null || loginData.password == null) ) {
  	// this is the end
    	reminderFox_downloadCallback(reminderFox_getBundle().getString("rf.upload.noPasswordSet.label"),3);
    	return;
  }
  
  if ( loginData == null ) {
	_downloadURL = proto + "://" + address;
  }
  else {
	  // uri-encode username and password
	  _username = encodeURIComponent( _username );
	  var _password = encodeURIComponent (loginData.password );
	  _downloadURL = proto + "://" + _username + ":" + _password + "@" + address;
  }  
  
  
  var downloadURI = _ioService.newURI(_downloadURL,null,null);
  //statustxt("DEBUG VYPIS!",0);
  
  //gStartTime = new Date().getTime();

  if(gDownloadService.start(downloadURI,reminderFox_downloadCallback))
    reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.request.label"),0);
  else {
    //statustxt(reminderFox_getBundle().getString("rf.net.done"),0);
    reminderFox_downloadCallback(reminderFox_getBundle().getString("rf.net.done"),-1);
  }
}

function reminderFox_downloadCallback(aStatus,aError) {
	if(aStatus != reminderFox_getBundle().getString("rf.net.done") && aError==0) {
	    reminderFox_download_statustxt(aStatus,aError);
	    return;
	}


  switch(aError){
	  case -2:
	    reminderFox_download_statustxt(aStatus,aError);
		if (reminderFox_editWindowCallback != null ) {
			var statustxt = (aError)?	reminderFox_download_getErrorMsg(aError):aStatus;
	 		reminderFox_editWindowCallback (statustxt, -1  );
		}    
	    return;
	    break;
	  case 0:
	  	var remotetimestamp = reminderFox_getFileTimeStampFromString( gDownloadService.data );
	    var  lastRecordedLocalTimeStamp = reminderFox_prefs.getCharPref(REMINDER_FOX_PREF + "." + REMINDER_FOX_LAST_MODIFIED) + "";
	    
	    if ( remotetimestamp == -1 ) {
	    	// when syncing with a remote calendaring service (such as memotoo.com) and not just with other ReminderFox
	    	// instances, the remote file will not have the ReminderFox-last-modified timestamp.  In that case we will just assume
	    	// that the remote file is the master list (by treating it as a newer timestamp) and download them.  
	    	// This means on download, the remote always wins, so on upload you want to make sure that your local reminders
	    	// are uploaded and current; otherwise the remote reminders will overwrite local changes the next download attempt.
	    	remotetimestamp = new Date().getTime();
	    	reminderFox_logMessageLevel( "Remote reminders have no timestamp; assume they are newer... ", REMINDER_FOX_LOG_LEVEL_FINE);    	
	    }
	    
	    // if we are calling Download from the options, force it to download whether the remote reminders are newer or not...
	   	if (window.arguments != null && window.arguments[0] != null && window.arguments[0].forceDownload == true) {   		
	   		    reminderFox_download_statustxt(aStatus,aError);
	   		    lastRecordedLocalTimeStamp = -2;   // use  -2, as if there's no timestamp in the remote file, it comes back as -1.  So we need to be less than that value
	   	}
	   	
	  	var done = false;
	   	if ( remotetimestamp == lastRecordedLocalTimeStamp ) {
	  		reminderFox_logMessageLevel("Remote and Local reminders are identical: " + remotetimestamp, REMINDER_FOX_LOG_LEVEL_FINE);
	  		
			if (reminderFox_editWindowCallback != null ) {
				reminderFox_editWindowCallback ( null, 1  );
			}
	
	  		if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI ) {
	  			reminderFox_closeWindow();
	  		}		 
			return;
	  	}
	  	else if ( remotetimestamp < lastRecordedLocalTimeStamp ) {
	  	 	reminderFox_logMessageLevel("Local  reminders are newer than remote --  uploading local reminders... (local: " + lastRecordedLocalTimeStamp + ", remote: " + remotetimestamp + ")", REMINDER_FOX_LOG_LEVEL_FINE);
	   	 	reminderFox_logMessageLevel("Read timestamp from file (should be == to local): " + reminderFox_getFileTimeStamp(), REMINDER_FOX_LOG_LEVEL_FINE);
			if (reminderFox_editWindowCallback != null ) {		
				reminderFox_editWindowCallback ( reminderFox_getBundle().getString("rf.add.network.status.upload.label"), 0  );
			}
	  		// don't upload if this was called from the options window...
	  		if ( window.arguments != null && window.arguments[0] != null && window.arguments[0].closeOnNoErrors == 1) {  
	   		 	 setTimeout(reminderFox_uploadReminders, 0);
	  		} 	 
	  		
	  		if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS ) {		
	  			reminderFox_upload_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS );
			 }
	    	if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI ) {
	  			setTimeout( reminderFox_closeWindow, 1 );
	  		}
	  		
	  		if (reminderFox_editWindowCallback != null ) {		
				reminderFox_editWindowCallback (null, 1 );
			}
	  		
			return;
	  	}  
	  	else if ( remotetimestamp > lastRecordedLocalTimeStamp ) {
	  	 	reminderFox_logMessageLevel( "Remote reminders newer than local -- downloading remote reminders... (local: " + lastRecordedLocalTimeStamp + ", remote: " + remotetimestamp + ")", REMINDER_FOX_LOG_LEVEL_FINE);
	  	 	reminderFox_logMessageLevel("Read timestamp from file (should be == to local): " + reminderFox_getFileTimeStamp(), REMINDER_FOX_LOG_LEVEL_FINE);
	
			if (reminderFox_editWindowCallback != null ) {
	  	 		reminderFox_editWindowCallback ( reminderFox_getBundle().getString("rf.add.network.status.download.label"), 0  );
			}
			  var processtime = 0;
			     if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI) {
			    		processtime = document.getElementById("processtime");
			    	}
			    var time=gDownloadService.time;
			    processtime.value=gDownloadService.length.toString()
			                      +" bytes  "+(time/1000).toString() + " sec  ";
			    var start=new Date();
	
			    reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.upload.process.label"),0);
			    try{
			    	reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.download.importing.label"),0);
				
					var is = Components.classes["@mozilla.org/io/string-input-stream;1"]
						.createInstance( Components.interfaces.nsIStringInputStream );
					is.setData(gDownloadService.data,-1); // -1 ... length should be computed
					
					reminderEvents = new Array();
					reminderTodos = new Array();
					var originalExtraInfos = reminderFoxExtraInfo;
					reminderFox_readInRemindersAndTodosICSFromStream(reminderEvents, reminderTodos, is);
		
					// check to see if any todos in remote file...
					var hasTodos = false;  			 
				  	for ( var n in reminderTodos ) {
						var reminderFoxTodos = reminderTodos[n];
						if (reminderFoxTodos.length > 0  ) {
							hasTodos = true;
							break;
						}	  	
				  	}
	  				
	  				// safety check: if there are no events and no todo's in the remote file, we will assume that this an error condition 
	  				// (this happens frequently with icalx.com where the remote file gets cleared) and will not overwrite the local reminders
					if ( reminderEvents.length == 0 && !hasTodos ) {			  					  		
				  		reminderFox_logMessageLevel( 
				  			"Failed: remote file with timestamp " + remotetimestamp + " has no events or todo's...", REMINDER_FOX_LOG_LEVEL_FINE);
				  			reminderFoxExtraInfo = originalExtraInfos;  // switch back to original extra info	  		
				  		  // WE DON'T WANT TO OVERWRITE LOCAL IF NO REMOTE...			  		  		
	  				}
	  				else {
	  					// Overwrite
						reminderFoxEvents = reminderEvents;
						reminderFoxTodosArray = reminderTodos;
						reminderFox_importRemindersUpdateAll(true, remotetimestamp);
	  				}										
							    
				    // if successful, close immediately
				 	if ( window.arguments != null && window.arguments[0] != null && window.arguments[0].closeOnNoErrors == 1) {
				  		close();
				  		return;
				  	}
		
			        var end=new Date();
			        processtime.value += ((end.getTime() - start.getTime())/1000).toString()+" sec";
			        reminderFox_download_statustxt(reminderFox_getBundle().getString("rf.net.done"),0);
					
					if (reminderFox_editWindowCallback != null ) {
			  	 		reminderFox_editWindowCallback (null, 2  );
					}		        
			        
			    }catch(e){
			      reminderFox_download_statustxt(e.toString(),0);
			      if(e && e.toString().match(/^rem\:(.+)$/))
			        reminderFox_download_statustxt(RegExp.$1,0);
			      return;
			    }	
	  	}
	  
	    break;
	  default:
	    var status=aError % 0x804b0000;  
	    if ( status == 22 ) {
	      	reminderFox_logMessageLevel( "No remote file -- uploading local reminders...", REMINDER_FOX_LOG_LEVEL_FINE);
	
	  		// don't upload if this was called from the options window...
	  		if ( window.arguments != null && window.arguments[0] != null && window.arguments[0].closeOnNoErrors == 1) {
	  		 	 setTimeout(reminderFox_uploadReminders, 0);
	  		} 	 
	  		else if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS ) {
	 			reminderFox_upload_Startup_headless(REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ERRORS );
			 }
	    	if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI ) {
	  			setTimeout( reminderFox_closeWindow, 1 );
	  		}
	  		 if (reminderFox_editWindowCallback != null ) {		
				reminderFox_editWindowCallback (null, 1 );
			}
		}
		else {
	  	    reminderFox_download_statustxt(aStatus,aError);
			if (reminderFox_editWindowCallback != null ) {
				var statustxt = null;
				if (aError == -1) {
					statustxt = aStatus;
				}
				else {
					statustxt = (aError) ? reminderFox_download_getErrorMsg(aError) : aStatus;
				}
				
		 		reminderFox_editWindowCallback (statustxt, -1  );
			}      	  
	        break;
	     }
	  }
	  if ( aError == 0 ) { 
	      if ( reminderFox_download_headless == REMINDER_FOX_UI_MODE_HEADLESS_SHOW_ALL_UI) {
			reminderFox_closeWindow();
	  	  }
	  }
}


function reminderFox_closeWindow() {
 	if ( window.arguments != null && window.arguments[0] != null && window.arguments[0].closeOnNoErrors == 1) {
  		close();
  	}
  	else {
 	  	var reminderFox_download_button= document.getElementById("reminderFox_download_button");
  	  	reminderFox_download_button.setAttribute("label",reminderFox_getBundle().getString("rf.net.done")); 	
  	}
}




function reminderFox_cancelDownload()
{
  gDownloadService.cancel();
  close();
}


function reminderFox_download_getErrorMsg(aStatus)
{
  if(aStatus==0)
    return "ok";

  var status=aStatus % 0x804b0000;
  var error=reminderFox_getBundle().getString("rf.upload.unexpected.label");
  switch(status)
  {
    case 1:
      error=reminderFox_getBundle().getString("rf.upload.unexpected.label");
      break;
    case 2:
      error=reminderFox_getBundle().getString("rf.upload.usercancel.label");
      break;
	case 3:
      error=reminderFox_getBundle().getString("rf.upload.noPasswordSet.label");
      break;
    case 13:
      error=reminderFox_getBundle().getString("rf.upload.refused.label");
      break;
    case 14:
      error=reminderFox_getBundle().getString("rf.upload.netTimeout.label");
      break;
    case 16:
      error=reminderFox_getBundle().getString("rf.upload.netOffline.label");
      break;
    case 21:
      error=reminderFox_getBundle().getString("rf.upload.loginfailure.label");
      break;
    case 22:
      error=reminderFox_getBundle().getString("rf.upload.ftpcwd.label");
      break;
    case 23:
      error=reminderFox_getBundle().getString("rf.upload.ftppasv.label");
      break;
    case 24:
      error=reminderFox_getBundle().getString("rf.upload.ftppwd.label");
      break;
    case 25:
      error=reminderFox_getBundle().getString("rf.upload.ftplist.label");
      break;
    case 30:
      error=reminderFox_getBundle().getString("rf.upload.unknown.label");
      break;
    case 201:
      error=reminderFox_getBundle().getString("rf.upload.created.label");
      break;
    case 401:
      error=reminderFox_getBundle().getString("rf.upload.loginfailure.label");
      break;
    case 405:
      error=reminderFox_getBundle().getString("rf.upload.methodNotAllowed.label");
      break;
    default:
      error=reminderFox_getBundle().getString("rf.upload.unexpected.label");
      break;
  }

  var formatted= (aStatus<0x804b0000)?
          aStatus.toString(10) : "0x" + aStatus.toString(16).toUpperCase();
  return error + " (" + formatted +")";
}




